package com.game.logic.core.scene;


import com.game.logic.core.scene.entry.MapEntry;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Set;

/// 状态同步
// @todo 后续补充帧顺序管理
@Slf4j
public class StateSynchronizer<T> {
    /// 同步锁对象
    private final Object lock = new Object();
    
    /// 加入同步的实体
    private final Set<MapEntry<T>> entrySet;

    /// 未同步的状态
    private final List<Object> unsynchronizedStateList;

    public StateSynchronizer() {
        entrySet = new java.util.HashSet<>();
        unsynchronizedStateList = new java.util.ArrayList<>();
    }

    /// 添加一个实体
    public void addEntry(MapEntry<T> vector2Entry) {
        entrySet.add(vector2Entry);
        addSynchronize(vector2Entry);
    }

    /// 移除一个实体
    public void removeEntry(MapEntry<T> vector2Entry) {
        entrySet.remove(vector2Entry);
    }

    /// 添加一个同步信息
    public void addSynchronize(Object synchronize) {
        synchronized (lock) {
            log.debug("添加同步信息: {}", synchronize);
            unsynchronizedStateList.add(synchronize);
        }
    }

    /// 同步状态
    public void synchronize() {
        List<Object> toSync;
        
        // 对临界区进行同步保护
        synchronized (lock) {
            // 避免并发修改异常，先复制列表再清空
            if (unsynchronizedStateList.isEmpty()) {
                return;
            }
            
            toSync = new java.util.ArrayList<>(unsynchronizedStateList);
            unsynchronizedStateList.clear();
        }
        
        // 批量同步状态
        for (Object unSynchronized : toSync) {
            for (MapEntry<T> vector2Entry : entrySet) {
                vector2Entry.push(unSynchronized);
            }
        }
        
        // 手动销毁临时列表，释放内存
        toSync.clear();
    }

    public MapEntry<T> selectEntry(int hash) {
        for (MapEntry<T> entry : entrySet) {
            if (entry.hashCode() == hash) {
                return entry;
            }
        }
        return null;
    }
}
